Skip to content

Use dlopen to load NCCL EP - #3434

Open
fheinecke wants to merge 7 commits into
NVIDIA:mainfrom
fheinecke:fred/dlopen-nccl-ep-1
Open

Use dlopen to load NCCL EP#3434
fheinecke wants to merge 7 commits into
NVIDIA:mainfrom
fheinecke:fred/dlopen-nccl-ep-1

Conversation

@fheinecke

Copy link
Copy Markdown
Collaborator

Description

NCCL EP is currently linked statically into the TE core shared library. This PR moves from statically linking to dlopening the file at runtime, but only when NCCL EP features are needed.

This solves two problems:

  • Unblocks BOLT optimization. BOLT optimization requires setting the -z now flag, which resolves all symbols at dynamic load time. This means that even if NCCL EP isn't used, it's dependencies symbols are still resolved. Because NCCL EP features require a newer version of NCCL than the rest of TE, this means that enabling BOLT optimization raises the minimum NCCL version. By dlopening NCCL EP instead, resolution of these symbols controlled by TE, and can be limited to only be loaded when NCCL EP features are used.
  • NCCL EP JIT header files are missing, causing JIT compilation to fail. NCCL lib and include are now shipped with TE as a part of this work.

Type of change

  • Documentation change (change only to the documentation, either a fix or a new content)
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Infra/Build change
  • Code refactoring

Changes

Please list the changes introduced in this PR:

  • Ship NCCL EP dynamic library with TE
  • Fix missing NCCL EP JIT headers not being shipped with TE

Checklist:

  • I have read and followed the contributing guidelines
  • The functionality is complete
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
@fheinecke
fheinecke requested a review from ptrendx as a code owner August 27, 2026 21:53
@fheinecke
fheinecke requested a review from phu0ngng August 27, 2026 21:53
Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
@fheinecke
fheinecke force-pushed the fred/dlopen-nccl-ep-1 branch from 1873e7b to fdded06 Compare August 27, 2026 21:54
@fheinecke fheinecke added the 2.19 label Aug 27, 2026
@greptile-apps

greptile-apps Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves NCCL EP from static linkage to on-demand runtime loading and packages its shared library and JIT headers with Transformer Engine. The revised native discovery now handles compatible fully versioned libraries, but Python availability detection still accepts incompatible-major files.

  • Adds a runtime NCCL EP symbol provider and redirects EP operations through it.
  • Packages libnccl_ep.so and the headers required for JIT compilation.
  • Adds wheel, discovery, and distributed JIT validation.

Confidence Score: 4/5

The PR should not merge until Python availability detection rejects NCCL EP libraries that the native loader cannot load because of a major-version mismatch.

An incompatible-major file under NCCL_EP_HOME currently passes the public availability checks but is excluded or rejected during native EP initialization.

Files Needing Attention: transformer_engine/init.py and transformer_engine/common/ep/nccl_ep_provider.cpp

Important Files Changed

Filename Overview
transformer_engine/common/ep/nccl_ep_provider.cpp Implements lazy library discovery, major-version validation, JIT environment setup, and runtime symbol dispatch.
transformer_engine/init.py Adds Python-side NCCL EP discovery, but its NCCL_EP_HOME glob does not enforce the native loader's major-version requirement.
transformer_engine/common/CMakeLists.txt Replaces static NCCL EP linkage with runtime-provider compilation and packages the shared library and JIT headers.
build_tools/build_ext.py Moves the staged NCCL EP header directory into the release wheel library layout.
tests/pytorch/test_nccl_ep_discovery.py Covers home, packaged, dynamic-loader, and missing-library discovery, but not an incompatible-major home library.

Sequence Diagram

sequenceDiagram
  participant App
  participant Python as Python availability check
  participant Backend as EPBackend
  participant Loader as NCCL EP loader
  participant Library as libnccl_ep.so
  App->>Python: is_nccl_ep_available()
  Python->>Python: "Match NCCL_EP_HOME/lib/libnccl_ep.so*"
  Python-->>App: Available
  App->>Backend: Initialize EP
  Backend->>Backend: Validate NCCL runtime
  Backend->>Loader: initialize()
  Loader->>Loader: Select matching NCCL_EP_MAJOR candidate
  Loader->>Library: dlopen and validate version
  Library-->>Backend: Symbols or load error
Loading

Reviews (3): Last reviewed commit: "switch provider to use `call_symbol`" | Re-trigger Greptile

Comment thread transformer_engine/__init__.py
Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
Comment thread build_tools/build_ext.py
Comment on lines +179 to +183
shutil.rmtree(target_nccl_ep_dir)
shutil.copytree(
nccl_ep_dir,
target_nccl_ep_dir,
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we copy the whole nccl_ep dir instead of header files only?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole built dir, but not the entire source repo. Here's what should be shipped:

transformer_engine/wheel_lib/
├── libtransformer_engine.so
├── libnccl_ep.so
└── nccl_ep/
    └── include/
        ├── nccl_ep.h
        └── nccl_ep/
            ├── config.h
            ├── common.hpp
            ├── ep_enums.h
            └── device/
                └── *.cuh



def test_nccl_ep_library_not_found(monkeypatch):
monkeypatch.delenv("NCCL_EP_HOME", raising=False)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it mean NCCL_EP_HOME needs to be set at runtime?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, but it's set automatically via nccl_ep_provider.cpp here. This allows users to continue using the TE shared lib directly without needing to explicitly set the var.

Comment thread transformer_engine/common/ep/nccl_ep_provider.cpp
Comment thread transformer_engine/common/__init__.py Outdated
Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
Signed-off-by: Fred Heinecke <fheinecke@nvidia.com>
@fheinecke

Copy link
Copy Markdown
Collaborator Author

/te-ci

@fheinecke
fheinecke requested a review from phu0ngng August 28, 2026 18:39
Comment thread transformer_engine/__init__.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants